#!/bin/bash

# Flutter APK一键打包脚本
# 支持多种构建模式和自动化配置

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
NC='\033[0m' # No Color

# 打印带颜色的消息
print_message() {
    echo -e "${2}${1}${NC}"
}

print_success() {
    print_message "$1" "$GREEN"
}

print_error() {
    print_message "$1" "$RED"
}

print_warning() {
    print_message "$1" "$YELLOW"
}

print_info() {
    print_message "$1" "$BLUE"
}

print_header() {
    print_message "$1" "$PURPLE"
}

# 显示帮助信息
show_help() {
    echo "Flutter APK一键打包脚本"
    echo
    echo "用法: $0 [选项]"
    echo
    echo "选项:"
    echo "  -t, --type TYPE     构建类型 (apk|appbundle|both) [默认: apk]"
    echo "  -m, --mode MODE     构建模式 (debug|profile|release) [默认: release]"
    echo "  -f, --flavor FLAVOR 构建渠道 (可选)"
    echo "  -o, --output DIR    输出目录 [默认: build/outputs]"
    echo "  -c, --clean         构建前清理"
    echo "  -s, --sign          检查签名配置"
    echo "  -v, --verbose       详细输出"
    echo "  -h, --help          显示帮助信息"
    echo
    echo "示例:"
    echo "  $0                           # 构建release APK"
    echo "  $0 -t appbundle              # 构建App Bundle"
    echo "  $0 -t both -c                # 清理并构建APK和App Bundle"
    echo "  $0 -m debug -v               # 构建debug APK (详细输出)"
    echo "  $0 -f prod -o ./releases     # 构建prod渠道到指定目录"
}

# 默认配置
BUILD_TYPE="apk"
BUILD_MODE="release"
BUILD_FLAVOR=""
OUTPUT_DIR="build/outputs"
CLEAN_BUILD=false
CHECK_SIGNING=false
VERBOSE=false

# 解析命令行参数
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -t|--type)
                BUILD_TYPE="$2"
                shift 2
                ;;
            -m|--mode)
                BUILD_MODE="$2"
                shift 2
                ;;
            -f|--flavor)
                BUILD_FLAVOR="$2"
                shift 2
                ;;
            -o|--output)
                OUTPUT_DIR="$2"
                shift 2
                ;;
            -c|--clean)
                CLEAN_BUILD=true
                shift
                ;;
            -s|--sign)
                CHECK_SIGNING=true
                shift
                ;;
            -v|--verbose)
                VERBOSE=true
                shift
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            *)
                print_error "未知参数: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

# 验证参数
validate_arguments() {
    case $BUILD_TYPE in
        apk|appbundle|both)
            ;;
        *)
            print_error "无效的构建类型: $BUILD_TYPE (支持: apk, appbundle, both)"
            exit 1
            ;;
    esac
    
    case $BUILD_MODE in
        debug|profile|release)
            ;;
        *)
            print_error "无效的构建模式: $BUILD_MODE (支持: debug, profile, release)"
            exit 1
            ;;
    esac
}

# 检查环境
check_environment() {
    print_info "检查构建环境..."
    
    # 检查Flutter
    if ! command -v flutter &> /dev/null; then
        print_error "错误: 未找到Flutter命令"
        exit 1
    fi
    
    # 检查FVM
    if [ -f ".fvm/fvm_config.json" ]; then
        if ! command -v fvm &> /dev/null; then
            print_error "错误: 检测到FVM配置但未找到FVM命令"
            exit 1
        fi
        FLUTTER_CMD="fvm flutter"
        print_info "使用FVM管理的Flutter版本"
    else
        FLUTTER_CMD="flutter"
    fi
    
    # 获取Flutter版本
    FLUTTER_VERSION=$($FLUTTER_CMD --version | head -n 1)
    print_info "Flutter版本: $FLUTTER_VERSION"
    
    # 检查项目
    if [ ! -f "pubspec.yaml" ]; then
        print_error "错误: 当前目录不是Flutter项目"
        exit 1
    fi
    
    # 检查Android配置
    if [ ! -d "android" ]; then
        print_error "错误: 未找到Android配置目录"
        exit 1
    fi
}

# 检查签名配置
check_signing_config() {
    if [ "$BUILD_MODE" = "release" ] || [ "$CHECK_SIGNING" = true ]; then
        print_info "检查签名配置..."
        
        KEY_PROPERTIES="android/key.properties"
        if [ ! -f "$KEY_PROPERTIES" ]; then
            print_warning "警告: 未找到签名配置文件 $KEY_PROPERTIES"
            print_info "使用以下命令生成签名配置:"
            print_info "  ./scripts/generate_keystore.sh"
            
            if [ "$BUILD_MODE" = "release" ]; then
                read -p "是否继续使用debug签名? (y/N): " CONTINUE_DEBUG
                if [[ ! $CONTINUE_DEBUG =~ ^[Yy]$ ]]; then
                    exit 1
                fi
                print_warning "使用debug签名构建release版本"
            fi
        else
            print_success "✓ 签名配置文件存在"
            
            # 验证keystore文件
            STORE_FILE=$(grep "storeFile=" "$KEY_PROPERTIES" | cut -d'=' -f2)
            KEYSTORE_PATH="android/app/$STORE_FILE"
            if [ ! -f "$KEYSTORE_PATH" ]; then
                print_error "错误: Keystore文件不存在: $KEYSTORE_PATH"
                exit 1
            fi
            print_success "✓ Keystore文件存在"
        fi
    fi
}

# 获取应用信息
get_app_info() {
    APP_NAME=$(grep "name:" pubspec.yaml | head -n 1 | cut -d':' -f2 | xargs)
    APP_VERSION=$(grep "version:" pubspec.yaml | head -n 1 | cut -d':' -f2 | xargs)
    
    print_info "应用名称: $APP_NAME"
    print_info "应用版本: $APP_VERSION"
}

# 清理构建
clean_build() {
    if [ "$CLEAN_BUILD" = true ]; then
        print_info "清理构建缓存..."
        $FLUTTER_CMD clean
        print_success "✓ 构建缓存已清理"
    fi
}

# 获取依赖
get_dependencies() {
    print_info "获取依赖包..."
    $FLUTTER_CMD pub get
    print_success "✓ 依赖包获取完成"
}

# 构建APK
build_apk() {
    print_header "==== 构建APK ===="
    
    BUILD_CMD="$FLUTTER_CMD build apk --$BUILD_MODE"
    
    if [ -n "$BUILD_FLAVOR" ]; then
        BUILD_CMD="$BUILD_CMD --flavor $BUILD_FLAVOR"
    fi
    
    if [ "$VERBOSE" = true ]; then
        BUILD_CMD="$BUILD_CMD --verbose"
    fi
    
    print_info "执行命令: $BUILD_CMD"
    
    if $BUILD_CMD; then
        print_success "✓ APK构建成功"
        
        # 查找生成的APK文件
        if [ -n "$BUILD_FLAVOR" ]; then
            APK_PATH="build/app/outputs/flutter-apk/app-$BUILD_FLAVOR-$BUILD_MODE.apk"
        else
            APK_PATH="build/app/outputs/flutter-apk/app-$BUILD_MODE.apk"
        fi
        
        if [ -f "$APK_PATH" ]; then
            APK_SIZE=$(du -h "$APK_PATH" | cut -f1)
            print_info "APK文件: $APK_PATH ($APK_SIZE)"
            
            # 复制到输出目录
            copy_to_output "$APK_PATH" "apk"
        else
            print_warning "警告: 未找到预期的APK文件"
            find build/app/outputs/flutter-apk/ -name "*.apk" | while read apk; do
                APK_SIZE=$(du -h "$apk" | cut -f1)
                print_info "找到APK: $apk ($APK_SIZE)"
                copy_to_output "$apk" "apk"
            done
        fi
    else
        print_error "✗ APK构建失败"
        exit 1
    fi
}

# 构建App Bundle
build_appbundle() {
    print_header "==== 构建App Bundle ===="
    
    BUILD_CMD="$FLUTTER_CMD build appbundle --$BUILD_MODE"
    
    if [ -n "$BUILD_FLAVOR" ]; then
        BUILD_CMD="$BUILD_CMD --flavor $BUILD_FLAVOR"
    fi
    
    if [ "$VERBOSE" = true ]; then
        BUILD_CMD="$BUILD_CMD --verbose"
    fi
    
    print_info "执行命令: $BUILD_CMD"
    
    if $BUILD_CMD; then
        print_success "✓ App Bundle构建成功"
        
        # 查找生成的AAB文件
        if [ -n "$BUILD_FLAVOR" ]; then
            AAB_PATH="build/app/outputs/bundle/${BUILD_FLAVOR}Release/app-$BUILD_FLAVOR-$BUILD_MODE.aab"
        else
            AAB_PATH="build/app/outputs/bundle/${BUILD_MODE}Release/app-$BUILD_MODE.aab"
        fi
        
        if [ -f "$AAB_PATH" ]; then
            AAB_SIZE=$(du -h "$AAB_PATH" | cut -f1)
            print_info "App Bundle文件: $AAB_PATH ($AAB_SIZE)"
            
            # 复制到输出目录
            copy_to_output "$AAB_PATH" "aab"
        else
            print_warning "警告: 未找到预期的App Bundle文件"
            find build/app/outputs/bundle/ -name "*.aab" | while read aab; do
                AAB_SIZE=$(du -h "$aab" | cut -f1)
                print_info "找到App Bundle: $aab ($AAB_SIZE)"
                copy_to_output "$aab" "aab"
            done
        fi
    else
        print_error "✗ App Bundle构建失败"
        exit 1
    fi
}

# 复制文件到输出目录
copy_to_output() {
    local source_file="$1"
    local file_type="$2"
    
    if [ ! -f "$source_file" ]; then
        return
    fi
    
    # 创建输出目录
    mkdir -p "$OUTPUT_DIR"
    
    # 生成文件名
    local timestamp=$(date "+%Y%m%d_%H%M%S")
    local filename=$(basename "$source_file")
    local name_without_ext="${filename%.*}"
    local extension="${filename##*.}"
    
    local output_filename="${APP_NAME}_v${APP_VERSION}_${BUILD_MODE}_${timestamp}.${extension}"
    local output_path="$OUTPUT_DIR/$output_filename"
    
    # 复制文件
    cp "$source_file" "$output_path"
    print_success "✓ 文件已复制到: $output_path"
    
    # 生成文件信息
    local file_size=$(du -h "$output_path" | cut -f1)
    local file_hash=$(shasum -a 256 "$output_path" | cut -d' ' -f1)
    
    # 保存构建信息
    cat >> "$OUTPUT_DIR/build_info.txt" << EOF
=== 构建信息 ===
文件类型: ${file_type^^}
文件名: $output_filename
文件大小: $file_size
SHA256: $file_hash
构建时间: $(date)
构建模式: $BUILD_MODE
应用版本: $APP_VERSION
Flutter版本: $FLUTTER_VERSION
签名状态: $([ -f "android/key.properties" ] && echo "已签名" || echo "Debug签名")

EOF
}

# 显示构建总结
show_summary() {
    print_header "==== 构建完成 ===="
    
    if [ -d "$OUTPUT_DIR" ]; then
        print_info "输出目录: $OUTPUT_DIR"
        find "$OUTPUT_DIR" -name "*.apk" -o -name "*.aab" | while read file; do
            local file_size=$(du -h "$file" | cut -f1)
            print_success "  ✓ $(basename "$file") ($file_size)"
        done
        
        if [ -f "$OUTPUT_DIR/build_info.txt" ]; then
            print_info "构建信息已保存到: $OUTPUT_DIR/build_info.txt"
        fi
    fi
    
    print_info "构建用时: $(($(date +%s) - START_TIME))秒"
}

# 主函数
main() {
    START_TIME=$(date +%s)
    
    print_header "==== Flutter APK构建脚本 ===="
    
    parse_arguments "$@"
    validate_arguments
    check_environment
    get_app_info
    check_signing_config
    clean_build
    get_dependencies
    
    case $BUILD_TYPE in
        apk)
            build_apk
            ;;
        appbundle)
            build_appbundle
            ;;
        both)
            build_apk
            build_appbundle
            ;;
    esac
    
    show_summary
}

# 捕获中断信号
trap 'print_error "构建被中断"; exit 130' INT

# 运行主函数
main "$@"